<?php

/*
 *	Framework namespace
 */
namespace Nano
{
	/*
	 *	MySQL class
	 *
	 *	@extends	\Kernel
	 */
	class MySQL extends \Kernel
	{
		/*
		 *	$host	sring	Server host
		 */
		private $host = 'localhost';
		
		/*
		 *	$port	int	Server port
		 */
		private $port = 3306;
		
		/*
		 *	$username	string	Database user
		 */
		private $username = 'root';
		
		/*
		 *	$password	string	Username password
		 */
		private $password;
		
		/*
		 *	$dbname	string	Database name
		 */
		private $dbname;
		
		/*
		 *	$dbprefix	string	Prefix of tables
		 */
		private $dbprefix;
		
		/*
		 *	$charset	string	Database charset
		 */
		private $charset = 'utf8';
		
		/*
		 *	$persistent	boolean	Is it persistent conenction?
		 */
		private $persistent = false;
		
		/*
		 *	$connection	resource	Connection
		 */
		private $connection = null;
		
		/*
		 *	$queries	array	Queries list
		 */
		private $queries = array();
		
		/*
		 *	Constructor
		 *
		 *	@param	string	Hostname
		 *	@param	int		Host port
		 *	@param	string	User
		 *	@param	string	Password
		 *	@param	string	Database name
		 *	@param	string	Database table prefix
		 *	@param	string	Charset
		 *	@param	boolean	For persistent conenction
		 */
		public function __construct($host, $port, $user, $password, $dbname, $dbprefix, $charset, $persistent)
		{
			$this->host = $host;
			
			$this->port = $port;
			
			$this->username = $user;
			
			$this->password = $password;
			
			$this->dbname = $dbname;
			
			$this->dbprefix = $dbprefix;
			
			$this->charset = $charset;
			
			$this->queries = array();
			
			$this->connection($persistent);
		}
		
		/*
		 *	Create MySQL connection
		 */
		public function connect($persistent = false)
		{
			if($persistent)
			{
				$this->connection = mysql_pconnect($this->host.':'.$this->port, $this->user, $this->pass, true);
			}
			else
			{
				$this->connection = mysql_connect($this->host.':'.$this->port, $this->user, $this->pass, true);
			}
			
			if(!mysql_select_db($this->database, $this->connection))
			{
				throw new \Exception('Could not select database "'.$this->database.'"');
			}
			
			if(!mysql_set_charset($this->charset, $this->connection))
			{	
				throw new \Exception('Could not set charset "'.$this->charset.'"');
			}
		}
		
		/*
		 *	Set data for query
		 *
		 *	@param	array	Query data
		 */
		public function set($data = array())
		{
			if(!is_array($data))
			{
				return false;
			}
			
			$this->qdata = $data;
		}
		
		/*
		 *	Execute query
		 *
		 *	@throw
		 *	@return boolean
		 */
		public function query($query, $is_file = false)
		{
			if(!$this->connectionion == null)
			{
				throw new \Exception('Could not make SQL query without connection');
			}
			
			// TODO: Make it safe
			if($is_file)
			{
				$query = Filesystem::get($query);
			}
			
			$query = trim($query);
			
			$query = str_replace('%pref%', $this->pref, $query);
			
			if(isset($this->qdata) && is_array($this->qdata))
			{
				$array = array();
				
				foreach($this->qdata as $key => $value)
				{
					$array[('%'.($key + 1))] = $this::safe($value);
				}
				
				$query = str_replace(array_keys($array), array_values($array), $query);
			}
			
			$this->result = mysql_query($query, $this->connectionion);
			
			$this->queries[] = $query;
			
			if(!$this->result)
			{
				throw new \Exception('MySQL query error: "'.$query.'"');
			}
			
			return true;
		}
		
		/*
		 *	Make string safty for query
		 *
		 *	@return string
		 */
		function safe($dirty)
		{
			if(empty($dirty))
			{
				return null;
			}
			
			if(!$this->connectioned)
			{
				return false;
			}
			
			if(get_magic_quotes_gpc())
			{
				$clean = mysql_real_escape_string(stripslashes($dirty), $this->connection);
		 	}
		 	else
		 	{
				$clean = mysql_real_escape_string($dirty, $this->connection);
			}
			
			return $clean;
		}
		
		/*
		 *	Clear data after query
		 */
		public function free($set = null)
		{
			if(!isset($set))
			{
				$set = $this->query;
			}
			
			mysql_free_result($set);
		}
		
		/*
		 *	Fetch row
		 *
		 *	@return	array
		 */
		public function fetch_row()
		{
			return mysql_fetch_row($this->result);
		}
		
		/*
		 *	Fetch array
		 *
		 *	@return	array
		 */
		public function fetch_array()
		{
			return mysql_fetch_array($this->result);
		}
		
		/*
		 *	Fetch assoc
		 *
		 *	@return	array
		 */
		public function fetch_assoc()
		{
			return mysql_fetch_assoc($this->result);
		}
		
		/*
		 *	Fetch MySQL result
		 *
		 *	@return	array
		 */
		public function fetch_all()
		{
			$return = array();
			
			while($row = $this->fetch_assoc())
			{
				$return[] = $row;
			}
			
			return $return;
	    }
	    
	    /*
	     *	Last inserted ID
	     *
	     *	@return	int
	     */
	    public function insert_id()
	    {
			return mysql_insert_id($this->connection);
		}
		
		/*
		 *	Ping mysql server
		 *
		 *	@return boolean
		 */
		public function ping()
		{
			return mysql_ping($this->connectionion);
		}
		
		/*
		 *	Get complete information about MySql connection
		 *
		 *	@return	array
		 */
		public function info()
		{
			if(!$this->connectioned)
			{
				return array();
			}
			
			return array
			(
				// MySQL queries
				'queries' => $this->queries,
				
				// MySQL host
				'host' => mysql_get_host_info($this->connection),
				
				// Connection alive?
				'connection' => ($this->ping($this->connection) ? 'alive' : 'dead'),
					
				// Protocol
				'protocol' => mysql_get_proto_info($this->connec),
					
				// Thred ID
				'thread' => mysql_thread_id($this->connection),
					
				// Charset
				'charset' => mysql_client_encoding($this->connection),
					
				// Server info
				'server' => array
				(
					'version' => mysql_get_server_info($this->connection)
				),
					
				// Client info
				'client' => array
				(
					'version' => mysql_get_client_info($this->connection)
				),
					
				// other statistic
				'statistic' => explode('  ', mysql_stat($this->connec)),
					
				// processes
				// 'processes' => mysql_list_processes($this->connection)
			);
		}
		
		/*
		 *	Destructor
		 *
		 *	Close connection
		 */
		public function __destruct()
		{
			if($this->connectioned or !$this->ping())
			{
				mysql_close($this->connection);
			}
		}
	}
}